package cn.bugstack.domain.strategy.service.rule.factory;

import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.service.annotation.LogicStrategy;
import cn.bugstack.domain.strategy.service.rule.ILogicFilter;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

import org.springframework.core.annotation.AnnotationUtils;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认规则引擎工厂
 * 根据rule_model判断是哪个策略
 */
@Slf4j
@Component
public class DefaultLogicFactory {

    // 第一种方式，在策略接口中添加选择哪个策略的方法，spring启动会自动加载
//    private final Map<String, ILogicFilter> strategies = new HashMap<>();
//
//    @Autowired
//    public DefaultLogicFactory(List<ILogicFilter> strategyList) {
//        for (ILogicFilter strategy : strategyList) {
//            strategies.put(strategy.getRuleModel(), strategy);
//        }
//        log.info("当前已注册策略类列表：{}", strategies.keySet());
//    }
//
//    public ILogicFilter getStrategy(String ruleModel) {
//        // 根据 rule_model 获取相应的策略
//        return strategies.get(ruleModel);
//    }

    //第二种方式，通过注解
    public Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();

    public DefaultLogicFactory(List<ILogicFilter<?>> logicFilters) {
        logicFilters.forEach(logic -> {
            // 找到添加LogicStrategy注解的类,也就是对应的不同策略，然后放入map中
            LogicStrategy strategy = AnnotationUtils.findAnnotation(logic.getClass(), LogicStrategy.class);
            if (null != strategy) {
                logicFilterMap.put(strategy.logicMode().getCode(), logic);
            }
        });
    }

    public <T extends RuleActionEntity.RaffleEntity> Map<String, ILogicFilter<T>> openLogicFilter() {
        return (Map<String, ILogicFilter<T>>) (Map<?, ?>) logicFilterMap;
    }

    @Getter
    @AllArgsConstructor
    public enum LogicModel {
        RULE_WIGHT("rule_weight", "【抽奖前规则】根据抽奖权重返回可抽奖范围KEY"),
        RULE_BLACKLIST("rule_blacklist", "【抽奖前规则】黑名单规则过滤，命中黑名单则直接返回");
        private final String code;
        private final String info;
    }
}
